home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 8 / Example 8.1 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  8.7 KB  |  317 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 8.1: Team Color                                    //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "skinnedmesh.h"
  10. #include "shader.h"
  11.  
  12. class APPLICATION
  13. {
  14.     public:
  15.         
  16.         APPLICATION();
  17.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  18.         HRESULT Update(float deltaTime);
  19.         HRESULT Render();
  20.         HRESULT Cleanup();
  21.         HRESULT Quit();
  22.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  23.  
  24.     private:
  25.         IDirect3DDevice9* m_pDevice; 
  26.         SKINNEDMESH m_skinnedMesh;
  27.  
  28.         DWORD m_time, m_pressTime;
  29.         int m_fps, m_lastFps, m_col;
  30.         float m_angle, m_unitTime, m_colFade;
  31.         D3DXVECTOR4 m_activeCol, m_lastCol, m_currentCol;
  32.         HWND m_mainWindow;
  33.         ID3DXFont *m_pFont;
  34.  
  35.         //Shaders
  36.         SHADER m_unitVS, m_unitPS;
  37.         D3DXHANDLE m_worldHandle, m_viewProjHandle, m_sunHandle, m_teamColHandle;
  38. };
  39.  
  40. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  41. {
  42.     APPLICATION app;
  43.  
  44.     if(FAILED(app.Init(hInstance, 800, 600, true)))return 0;
  45.  
  46.     MSG msg;
  47.     memset(&msg, 0, sizeof(MSG));
  48.     int startTime = timeGetTime(); 
  49.  
  50.     while(msg.message != WM_QUIT)
  51.     {
  52.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  53.         {
  54.             ::TranslateMessage(&msg);
  55.             ::DispatchMessage(&msg);
  56.         }
  57.         else
  58.         {    
  59.             int t = timeGetTime();
  60.             float deltaTime = (t - startTime)*0.001f;
  61.  
  62.             app.Update(deltaTime);
  63.             app.Render();
  64.  
  65.             startTime = t;
  66.         }
  67.     }
  68.  
  69.     app.Cleanup();
  70.  
  71.     return msg.wParam;
  72. }
  73.  
  74. APPLICATION::APPLICATION()
  75. {
  76.     m_pDevice = NULL; 
  77.     m_mainWindow = 0;
  78.     srand(GetTickCount());
  79.     m_fps = m_lastFps = m_col = 0;
  80.     m_angle = m_unitTime = m_colFade = 0.0f;
  81.     m_time = m_pressTime = GetTickCount();
  82.     m_currentCol = m_lastCol = m_activeCol = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);
  83. }
  84.  
  85. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  86. {
  87.     debug.Print("Application initiated");
  88.  
  89.     //Create Window Class
  90.     WNDCLASS wc;
  91.     memset(&wc, 0, sizeof(WNDCLASS));
  92.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  93.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  94.     wc.hInstance     = hInstance;
  95.     wc.lpszClassName = "D3DWND";
  96.  
  97.     //Register Class and Create new Window
  98.     RegisterClass(&wc);
  99.     m_mainWindow = CreateWindow("D3DWND", "Example 8.1: Team Color", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  100.     SetCursor(NULL);
  101.     ShowWindow(m_mainWindow, SW_SHOW);
  102.     UpdateWindow(m_mainWindow);
  103.  
  104.     //Create IDirect3D9 Interface
  105.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  106.  
  107.     if(d3d9 == NULL)
  108.     {
  109.         debug.Print("Direct3DCreate9() - FAILED");
  110.         return E_FAIL;
  111.     }
  112.  
  113.     //Check that the Device supports what we need from it
  114.     D3DCAPS9 caps;
  115.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  116.  
  117.     //Hardware Vertex Processing or not?
  118.     int vp = 0;
  119.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  120.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  121.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  122.  
  123.     //Check vertex & pixelshader versions
  124.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  125.     {
  126.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  127.     }
  128.  
  129.     //Set D3DPRESENT_PARAMETERS
  130.     D3DPRESENT_PARAMETERS d3dpp;
  131.     d3dpp.BackBufferWidth            = width;
  132.     d3dpp.BackBufferHeight           = height;
  133.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  134.     d3dpp.BackBufferCount            = 1;
  135.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  136.     d3dpp.MultiSampleQuality         = 0;
  137.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  138.     d3dpp.hDeviceWindow              = m_mainWindow;
  139.     d3dpp.Windowed                   = windowed;
  140.     d3dpp.EnableAutoDepthStencil     = true; 
  141.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  142.     d3dpp.Flags                      = 0;
  143.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  144.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  145.  
  146.     //Create the IDirect3DDevice9
  147.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  148.                                  vp, &d3dpp, &m_pDevice)))
  149.     {
  150.         debug.Print("Failed to create IDirect3DDevice9");
  151.         return E_FAIL;
  152.     }
  153.  
  154.     //Release IDirect3D9 interface
  155.     d3d9->Release();
  156.  
  157.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  158.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  159.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  160.  
  161.     m_skinnedMesh.Load("units/magician.x", m_pDevice);
  162.     m_skinnedMesh.SetAnimation("Run");
  163.  
  164.     //Set sampler state
  165.     for(int i=0;i<4;i++)
  166.     {
  167.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  168.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  169.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  170.     }
  171.  
  172.     //Setup shaders
  173.     m_unitVS.Init(m_pDevice, "shaders/lighting.vs", VERTEX_SHADER);
  174.     m_worldHandle = m_unitVS.GetConstant("matW");
  175.     m_viewProjHandle = m_unitVS.GetConstant("matVP");
  176.     m_sunHandle = m_unitVS.GetConstant("DirToSun");
  177.  
  178.     m_unitPS.Init(m_pDevice, "shaders/teamCol.ps", PIXEL_SHADER);
  179.     m_teamColHandle = m_unitPS.GetConstant("tmCol");
  180.  
  181.     return S_OK;
  182. }
  183.  
  184. HRESULT APPLICATION::Update(float deltaTime)
  185. {        
  186.     //Rotate unit
  187.     m_angle += deltaTime * 0.2f;
  188.     m_unitTime = deltaTime * 0.5f;
  189.     if(m_angle > D3DX_PI * 2.0f)m_angle -= D3DX_PI * 2.0f;
  190.  
  191.     //change color
  192.     m_colFade += deltaTime * 0.4f;
  193.     if(m_colFade > 1.0f)m_colFade = 1.0f;
  194.     m_currentCol = m_lastCol * (1.0f - m_colFade) + m_activeCol * m_colFade;
  195.  
  196.     if(KEYDOWN(VK_SPACE) && GetTickCount() - m_pressTime > 300)
  197.     {
  198.         m_pressTime = GetTickCount();
  199.         m_col++;
  200.         if(m_col > 11)m_col = 0;
  201.  
  202.         D3DXVECTOR4 tmColors[] = {D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f),
  203.                                   D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f),
  204.                                   D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f),
  205.                                   D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f),
  206.                                   D3DXVECTOR4(1.0f, 0.0f, 1.0f, 1.0f),
  207.                                   D3DXVECTOR4(0.0f, 1.0f, 1.0f, 1.0f),
  208.                                   D3DXVECTOR4(0.5f, 0.25f, 0.0f, 1.0f),
  209.                                   D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f),
  210.                                   D3DXVECTOR4(1.0f, 0.5f, 0.0f, 1.0f),
  211.                                   D3DXVECTOR4(0.0f, 0.25f, 0.0f, 1.0f),
  212.                                   D3DXVECTOR4(0.25f, 0.0f, 0.0f, 1.0f),
  213.                                   D3DXVECTOR4(0.0f, 0.0f, 0.25f, 1.0f)};
  214.         m_lastCol = m_currentCol;
  215.         m_activeCol = tmColors[m_col];
  216.         m_colFade = 0.0f;
  217.     }
  218.     else if(KEYDOWN(VK_ESCAPE))
  219.     {
  220.         Quit();
  221.     }
  222.  
  223.     return S_OK;
  224. }    
  225.  
  226. HRESULT APPLICATION::Render()
  227. {
  228.     // Clear the viewport
  229.     m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
  230.  
  231.     D3DVIEWPORT9 v,v2;
  232.     m_pDevice->GetViewport(&v);
  233.     v2 = v;
  234.  
  235.     v.Y = 200;
  236.     v.Height = 200;
  237.     m_pDevice->SetViewport(&v);
  238.     m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DXCOLOR(m_currentCol.x, m_currentCol.y, m_currentCol.z, 1.0f), 1.0f, 0);
  239.     m_pDevice->SetViewport(&v2);
  240.  
  241.     //FPS Calculation
  242.     m_fps++;
  243.     if(GetTickCount() - m_time > 1000)
  244.     {
  245.         m_lastFps = m_fps;
  246.         m_fps = 0;
  247.         m_time = GetTickCount();
  248.     }
  249.  
  250.     //Set camera
  251.     D3DXMATRIX view, proj, world, r, s;
  252.     D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 10.0f, -50.0f), &D3DXVECTOR3(0.0f, 4.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  253.     D3DXMatrixPerspectiveFovLH(&proj, 0.2f, 1.33333f, 0.01f, 1000.0f);
  254.     D3DXMatrixRotationYawPitchRoll(&r, m_angle, 0.0f, 0.0f);
  255.     D3DXMatrixScaling(&s, 1.2f, 1.2f, 1.2f);
  256.     world = s * r;
  257.  
  258.     m_pDevice->SetTransform(D3DTS_VIEW, &view);
  259.     m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  260.     m_pDevice->SetTransform(D3DTS_WORLD, &world);
  261.  
  262.     // Begin the scene 
  263.     if(SUCCEEDED(m_pDevice->BeginScene()))
  264.     {
  265.         m_unitVS.SetMatrix(m_worldHandle, world);
  266.         m_unitVS.SetMatrix(m_viewProjHandle, view * proj);
  267.  
  268.         D3DXVECTOR3 sun;
  269.         D3DXVec3Normalize(&sun, &D3DXVECTOR3(0.5f, 1.0f, -0.5));
  270.         m_unitVS.SetVector3(m_sunHandle, sun);
  271.  
  272.         m_unitPS.SetVector4(m_teamColHandle, m_currentCol);
  273.  
  274.         m_unitVS.Begin();
  275.         m_unitPS.Begin();
  276.         m_skinnedMesh.SetPose(world, NULL, m_unitTime);
  277.         m_skinnedMesh.Render(NULL);
  278.         m_unitPS.End();
  279.         m_unitVS.End();
  280.  
  281.         RECT r[] = {{10, 10, 0, 0}, {720, 10, 0, 0}};
  282.         m_pFont->DrawText(NULL, "Space: Change Team Color", -1, &r[0], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  283.  
  284.         //FPS
  285.         char number[50];
  286.         std::string text = "FPS: ";
  287.         text += _itoa(m_lastFps, number, 10);
  288.         m_pFont->DrawText(NULL, text.c_str(), -1, &r[1], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  289.  
  290.         // End the scene.
  291.         m_pDevice->EndScene();
  292.         m_pDevice->Present(0, 0, 0, 0);
  293.     }
  294.  
  295.     return S_OK;
  296. }
  297.  
  298. HRESULT APPLICATION::Cleanup()
  299. {
  300.     try
  301.     {
  302.         m_pFont->Release();
  303.         m_pDevice->Release();
  304.  
  305.         debug.Print("Application terminated");
  306.     }
  307.     catch(...){}
  308.  
  309.     return S_OK;
  310. }
  311.  
  312. HRESULT APPLICATION::Quit()
  313. {
  314.     ::DestroyWindow(m_mainWindow);
  315.     ::PostQuitMessage(0);
  316.     return S_OK;
  317. }